package emulator.hardware.nmos6502;

import java.util.Vector;

import emulator.hardware.HwByte;
import emulator.hardware.nmos6502.commands.*;
import emulator.hardware.nmos6502.operands.*;

public class CommandSet {
	private Vector<CommandDefinition> cset;
	private CommandDefinition nil;
	
	public CommandSet() {
		cset = new Vector<CommandDefinition>(256);
		nil = new CommandDefinition(new IllegalOpcode(), new NoOperand());
		for (int i = 0; i < cset.capacity(); i++)
			cset.add(i, nil);
		initCommands();
	}
	
	int getDefinitionCount() {
		int count = 0;
		for (int i = 0; i < cset.capacity(); i++)
			if (cset.get(i) != nil)
				count++;
		return count;
	}
	
	private void initCommands() {
		new ADC().register(this);
		new ANC().register(this);
		new AND().register(this);
		new ASL().register(this);
		new ASO().register(this);
		new AXS().register(this);

		new BCC().register(this);
		new BCS().register(this);
		new BEQ().register(this);
		new BIT().register(this);
		new BMI().register(this);
		new BNE().register(this);
		new BPL().register(this);
		new BRK().register(this);
		new BVC().register(this);
		new BVS().register(this);
		
		new CLC().register(this);
		new CLD().register(this);
		new CLI().register(this);
		new CLV().register(this);
		new CMP().register(this);
		new CPX().register(this);
		new CPY().register(this);

		new DEC().register(this);
		new DEX().register(this);
		new DEY().register(this);

		new EOR().register(this);
		
		new INC().register(this);
		new INX().register(this);
		new INY().register(this);
		
		new JMP().register(this);
		new JSR().register(this);
		
		new LDA().register(this);
		new LDX().register(this);
		new LDY().register(this);
		new LSR().register(this);

		new NOP().register(this);
		
		new ORA().register(this);
		
		new PHA().register(this);
		new PHP().register(this);
		new PLA().register(this);
		new PLP().register(this);

		new ROL().register(this);
		new ROR().register(this);
		new RTI().register(this);
		new RTS().register(this);
		
		new SBC().register(this);
		new SEC().register(this);
		new SED().register(this);
		new SEI().register(this);
		new STA().register(this);
		new STX().register(this);
		new STY().register(this);
		
		new TAX().register(this);
		new TAY().register(this);
		new TSX().register(this);
		new TXA().register(this);
		new TXS().register(this);
		new TYA().register(this);
	}

	public void defineCommand(int opcode, Command command, Operand operand)	{
		cset.set(opcode, new CommandDefinition(command, operand));
	}

	public void defineCommand(int opcode, Command command, Operand operand, int cycles)	{
		cset.set(opcode, new CommandDefinition(command, operand, cycles));
	}

	public CommandDefinition getCommand(HwByte opcode) {
		return cset.get((int) opcode.getNumber());
	}
}
